﻿
using Test30.Core;

namespace Test30.Engine
{
    public class TeleportAction : Action
    {
        public TeleportAction(Entity entity, Hit hit, int distance)
            : this(entity, hit, distance, false)
        {
        }
        public TeleportAction(Entity entity, int distance)
            : this(entity, null, distance, true)
        {
        }

        private TeleportAction(Entity entity, Hit hit, int distance, bool isWillful)
            : base(entity)
        {
            //### bob: use int to increase distance?
            _mHit = hit;
            _distance = distance;
            _isWillful = isWillful;
        }

        protected override ActionResult OnProcess()
        {
            if (!_isWillful && Entity.StandsFirm(_mHit))
            {
                return ActionResult.Done;
            }

            Vec pos;
            // try to find a destination at least half the max distance away, but settle for closer if needed
            int maxDistance = _distance;
            int minDistance = _distance / 2;
            while (!Dungeon.TryFindOpenTileWithin(Entity.Position, _distance / 2, _distance, out pos) && (maxDistance > 1))
            {
                // decrease the distance
                maxDistance = minDistance - 1;
                minDistance = maxDistance / 2;
            }

            if (Entity.Position != pos)
            {
                Entity.Position = pos;
            }

            return ActionResult.Done;
        }

        private readonly Hit _mHit;
        private readonly int _distance;
        private readonly bool _isWillful;

    }
}
